package gu.simplemq;

import static gu.simplemq.utils.TypeConversionSupport.intValueOf;
import static gu.simplemq.utils.TypeConversionSupport.stringValueOf;
import static com.google.common.base.MoreObjects.firstNonNull;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;

import com.google.common.base.Strings;

import gu.simplemq.utils.TypeConversionSupport;

/**
 * 
 * 消息服务位置类型
 */
public enum MQLocationType implements Constant{
	/** 默认位置类型 */DEFAULT(MQ_URI,MQ_HOST,MQ_PORT),
	/** 订阅发布 */PUBSUB(MQ_PUBSUB_URI,MQ_PUBSUB_HOST,MQ_PUBSUB_PORT),
	/** 队列 */QUEUE(MQ_QUEUE_URI,MQ_QUEUE_HOST,MQ_QUEUE_PORT),
	/** WebSocket服务 */WS(MQ_WS_URI,MQ_WS_HOST,MQ_WS_PORT);
	public final String uriKey;
	public final String hostKey;
	public final String portKey;
	private MQLocationType(String uriKey, String hostKey, String portKey) {
		this.uriKey = uriKey;
		this.hostKey = hostKey;
		this.portKey = portKey;
	}
	/**
	 * 从Map中返回服务地址(URI)字符串
	 * @param props 为{@code null}返回{@code null}
	 * @param withDefault 如果没有找到是否查找默认类型{@link #DEFAULT}
	 * @param otherKeys 其他定义服务地址的关键字列表
	 * @return 服务地址(URI)字符串,没有返回{@code null}
	 */
	@SuppressWarnings("rawtypes")
	public String locationStringOf(Map props, boolean withDefault, String... otherKeys){
		if(null == props){
			return null;
		}
        Object v = props.get(uriKey);
        if((v instanceof String) && !((String) v).isEmpty()){
        	return (String) v;
        }else if(null != v){
        	return v.toString();
        }
        if(withDefault && !this.equals(DEFAULT) && !this.equals(WS)){
        	String s = DEFAULT.locationStringOf(props, false, otherKeys);
        	 if(!Strings.isNullOrEmpty(s)){
             	return s;
             }
        }
        if(otherKeys != null){
        	for(String key:otherKeys){
        		if(!Strings.isNullOrEmpty(key) && !key.equals(uriKey)){
        			v = props.get(key);
        	        if((v instanceof String) && !((String) v).isEmpty()){
        	        	return (String) v;
        	        }else if(null != v){
        	        	return v.toString();
        	        }
        		}
        	}
        }
        if(props.get(hostKey) != null || props.get(portKey) != null){
        	try {
        		String scheme = null;
        		if(this.equals(PUBSUB)){
        			if(TypeConversionSupport.convert(props.get(MQ_PUBSUB_MQTT), boolean.class)){
        				scheme = "mqtt";
        			}
        		}
        		return new URI(scheme, null,
        				stringValueOf(props,hostKey), 
        				firstNonNull(intValueOf(props,portKey),-1),null,null,null).toString();
        	} catch (URISyntaxException e) {
        		throw new RuntimeException(e);
        	}
        }
        return null;
	}
	/**
	 * 从Map中返回服务地址(URI)
	 * @param props 为{@code null}返回{@code null}
	 * @param withDefault 如果没有找到是否查找默认类型{@link #DEFAULT}
	 * @param otherKeys 其他定义服务地址的关键字列表
	 * @return 服务地址(URI)实例,没有返回{@code null}
	 */
	@SuppressWarnings({ "rawtypes"})
	public URI locationOf(Map props, boolean withDefault, String... otherKeys){
		String uri = locationStringOf(props, withDefault, otherKeys);
        return null == uri ? null : URI.create(uri);
	}
}